package com.ldoublem.loadingviewlib.view;



import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrHelper;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.render.Texture;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.media.image.common.Size;

import com.ldoublem.loadingviewlib.utils.ArgbEvaluator;
import com.ldoublem.loadingviewlib.view.base.LVBase;

import static ohos.media.image.common.PixelFormat.ARGB_8888;

public class LVBlazeWood extends LVBase implements Component.EstimateSizeListener, Component.DrawTask,
        Component.LayoutRefreshedListener {


    private int mWidth;
    private Paint mPaintBg;
    private Paint mPaintWood;
    private Paint mPaintFire;
    private RectFloat rectFBg;
    private RectFloat rectFWood;
    private int mPadding;
    private int woodWidth;
    private int woodLength;
    private PixelMap wood;

    private int getMeasuredHeight;
    private int getMeasuredWidth;
    private int oldH;
    private int oldW;

    public LVBlazeWood(Context context) {
        super(context);
    }

    public LVBlazeWood(Context context, AttrSet attrs) {
        super(context, attrs);
    }

    public LVBlazeWood(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    private void initPaint() {
        setEstimateSizeListener(this);
        addDrawTask(this);
        setLayoutRefreshedListener(this);
        evaluator = new ArgbEvaluator();
        mPadding = dip2px(1);
        mPaintBg = new Paint();
        mPaintBg.setAntiAlias(true);
        mPaintBg.setStyle(Paint.Style.FILL_STYLE);
        mPaintBg.setColor(Color.BLACK);

        mPaintWood = new Paint();
        mPaintWood.setAntiAlias(true);
        mPaintWood.setStyle(Paint.Style.FILL_STYLE);
        mPaintWood.setColor(new Color(Color.rgb(122, 57, 47)));


        mPaintFire = new Paint();
        mPaintFire.setAntiAlias(true);
        mPaintFire.setStyle(Paint.Style.FILL_STYLE);
        mPaintFire.setColor(new Color(Color.rgb(232, 132, 40)));
        oldH = this.getHeight();
        oldW = this.getWidth();

    }


    private PixelMap getWood() {
        if (wood != null) {
            return wood;
        }
        PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
        initializationOptions.size = new Size(getMeasuredWidth, getMeasuredHeight);
        initializationOptions.pixelFormat = ARGB_8888;
        wood = PixelMap.create(initializationOptions);


        Canvas canvas = null;
        canvas = new Canvas(new Texture(wood));

        canvas.rotate(-18, rectFWood.getCenter().getPointX(), rectFWood.getCenter().getPointY());
        mPaintWood.setColor(new Color(Color.rgb(97, 46, 37)));

        canvas.drawRoundRect(rectFWood, woodWidth / 5f, woodWidth / 5f, mPaintWood);
        canvas.rotate(36, rectFWood.getCenter().getPointX(), rectFWood.getCenter().getPointY());
        mPaintWood.setColor(new Color(Color.rgb(102, 46, 37)));


        canvas.drawRoundRect(rectFWood, woodWidth / 5f, woodWidth / 5f, mPaintWood);


        return wood;

    }

    RectFloat rectFire0 = new RectFloat();

    RectFloat rectFire1 = new RectFloat();
    RectFloat rectFire2 = new RectFloat();
    RectFloat rectFire3 = new RectFloat();
    ArgbEvaluator evaluator;


    private void drawFire0(Canvas canvas) {


        int color = (Integer) evaluator.evaluate(mAnimatedValue, Color.rgb(255, 220, 1),
                Color.rgb(240, 169, 47));

        mPaintFire.setColor(new Color(color));


        Path pathFire = new Path();

        RectFloat rectFire0 = new RectFloat();

        rectFire0.top = this.rectFire0.getCenter().getPointY() - (this.rectFire1.getHeight() / 2 - this.rectFire0.getHeight() / 2) * mAnimatedValue
                - (this.rectFire0.getCenter().getPointY() - this.rectFire1.getCenter().getPointY()) * mAnimatedValue

        ;
        rectFire0.bottom = this.rectFire0.getCenter().getPointY() + (this.rectFire1.getHeight() / 2 - this.rectFire0.getHeight() / 2) * mAnimatedValue
                - (this.rectFire0.getCenter().getPointY() - this.rectFire1.getCenter().getPointY()) * mAnimatedValue
        ;


        rectFire0.left = this.rectFire0.getCenter().getPointX() - (this.rectFire1.getWidth() / 2 - this.rectFire0.getWidth() / 2) * mAnimatedValue
                - rectFire1.getWidth() / 5 * mAnimatedValue;
        rectFire0.right = this.rectFire0.getCenter().getPointX() + (this.rectFire1.getWidth() / 2 - this.rectFire0.getWidth() / 2) * mAnimatedValue
                - rectFire1.getWidth() / 5 * mAnimatedValue;


        pathFire.moveTo(rectFire0.getCenter().getPointX(), rectFire0.top);
        pathFire.lineTo(rectFire0.right, rectFire0.getCenter().getPointY());
        pathFire.lineTo(rectFire0.getCenter().getPointX(), rectFire0.bottom);
        pathFire.lineTo(rectFire0.left, rectFire0.getCenter().getPointY());
        pathFire.close();

        canvas.drawPath(pathFire, mPaintFire);

    }


    private void drawFire1(Canvas canvas) {


        int color = (Integer) evaluator.evaluate(mAnimatedValue, Color.rgb(240, 169, 47), Color.rgb(232, 132, 40));

        mPaintFire.setColor(new Color(color));


        Path pathFire = new Path();

        RectFloat rectFire1 = new RectFloat();

        rectFire1.top = this.rectFire1.getCenter().getPointY() - this.rectFire1.getHeight() / 2
                - (this.rectFire2.getHeight() / 2 - this.rectFire1.getHeight() / 2) * mAnimatedValue
                - (this.rectFire1.getCenter().getPointY() - this.rectFire2.getCenter().getPointY()) * mAnimatedValue
        ;

        rectFire1.bottom = this.rectFire1.getCenter().getPointY() + this.rectFire1.getHeight() / 2
                + (this.rectFire2.getHeight() / 2 - this.rectFire1.getHeight() / 2) * mAnimatedValue
                - (this.rectFire1.getCenter().getPointY() - this.rectFire2.getCenter().getPointY()) * mAnimatedValue

        ;


        rectFire1.left = this.rectFire1.getCenter().getPointX() - this.rectFire1.getWidth() / 2
                - (this.rectFire2.getWidth() / 2 - this.rectFire1.getWidth() / 2) * mAnimatedValue
                + this.rectFire1.getWidth() / 5 * mAnimatedValue
        ;


        rectFire1.right = this.rectFire1.getCenter().getPointX() + this.rectFire1.getWidth() / 2 +
                +(this.rectFire2.getWidth() / 2 - this.rectFire1.getWidth() / 2) * mAnimatedValue
                + this.rectFire1.getWidth() / 5 * mAnimatedValue;


        pathFire.moveTo(rectFire1.getCenter().getPointX(), rectFire1.top);
        pathFire.lineTo(rectFire1.right, rectFire1.getCenter().getPointY());
        pathFire.lineTo(rectFire1.getCenter().getPointX(), rectFire1.bottom);
        pathFire.lineTo(rectFire1.left, rectFire1.getCenter().getPointY());
        pathFire.close();

        canvas.drawPath(pathFire, mPaintFire);


    }


    private void drawFire2(Canvas canvas) {

        int color = (Integer) evaluator.evaluate(mAnimatedValue, Color.rgb(232, 132, 40), Color.rgb(223, 86, 33));

        mPaintFire.setColor(new Color(color));

        RectFloat rectFire2 = new RectFloat();
        rectFire2.bottom = this.rectFire2.getCenter().getPointY() +
                rectFire3.getHeight() / 2 +
                +(this.rectFire2.getHeight() / 2 - rectFire3.getHeight() / 2) * (1 - mAnimatedValue)


                - (this.rectFire2.getCenter().getPointY() - this.rectFire3.getCenter().getPointY()) * mAnimatedValue


        ;


        rectFire2.top = this.rectFire2.getCenter().getPointY() -

                rectFire3.getHeight() / 2 +

                -(this.rectFire2.getHeight() / 2 - rectFire3.getHeight() / 2) * (1 - mAnimatedValue)

                - (this.rectFire2.getCenter().getPointY() - this.rectFire3.getCenter().getPointY()) * mAnimatedValue

        ;
        rectFire2.left = this.rectFire2.getCenter().getPointX()
                - rectFire3.getWidth() / 2 +


                -(this.rectFire2.getHeight() / 2 - rectFire3.getWidth() / 2) * (1 - mAnimatedValue)
                + (this.rectFire3.getWidth() / 3 * mAnimatedValue)


        ;
        rectFire2.right = this.rectFire2.getCenter().getPointX()
                + rectFire3.getWidth() / 2 +

                +(this.rectFire2.getHeight() / 2 - rectFire3.getWidth() / 2) * (1 - mAnimatedValue)

                + (this.rectFire3.getWidth() / 3 * mAnimatedValue)
        ;


        Path pathFire = new Path();
        pathFire.moveTo(rectFire2.getCenter().getPointX(), rectFire2.top);
        pathFire.lineTo(rectFire2.right, rectFire2.getCenter().getPointY());
        pathFire.lineTo(rectFire2.getCenter().getPointX(), rectFire2.bottom);
        pathFire.lineTo(rectFire2.left, rectFire2.getCenter().getPointY());
        pathFire.close();

        canvas.drawPath(pathFire, mPaintFire);


    }


    private void drawFire3(Canvas canvas) {


        mPaintFire.setColor(new Color(Color.rgb(223, 86, 33)));


        RectFloat rectFire3 = new RectFloat();
        rectFire3.bottom = this.rectFire3.getCenter().getPointY() + this.rectFire3.getHeight() / 2 * (1 - mAnimatedValue)
                - (this.rectFire3.getHeight()*0.75f) * mAnimatedValue;

        rectFire3.top = this.rectFire3.getCenter().getPointY() - this.rectFire3.getHeight() / 2 * (1 - mAnimatedValue)
                - (this.rectFire3.getHeight()*0.75f) * mAnimatedValue;
        rectFire3.left = this.rectFire3.getCenter().getPointX() - this.rectFire3.getHeight() / 2 * (1 - mAnimatedValue)

                - this.rectFire3.getHeight() / 3 * mAnimatedValue;


        rectFire3.right = this.rectFire3.getCenter().getPointX() + this.rectFire3.getHeight() / 2 * (1 - mAnimatedValue)
                - this.rectFire3.getHeight() / 3 * mAnimatedValue;
        ;


        Path pathFire = new Path();
        pathFire.moveTo(rectFire3.getCenter().getPointX(), rectFire3.top);
        pathFire.lineTo(rectFire3.right, rectFire3.getCenter().getPointY());
        pathFire.lineTo(rectFire3.getCenter().getPointX(), rectFire3.bottom);
        pathFire.lineTo(rectFire3.left, rectFire3.getCenter().getPointY());
        pathFire.close();

        canvas.drawPath(pathFire, mPaintFire);


    }


    private void initFire() {

        rectFire3.bottom = rectFBg.getCenter().getPointY() + woodLength / 5 - woodLength / 4;
        rectFire3.top = rectFBg.getCenter().getPointY() - woodLength / 5 - woodLength / 4;
        rectFire3.left = rectFBg.getCenter().getPointX() - woodLength / 5;
        rectFire3.right = rectFBg.getCenter().getPointX() + woodLength / 5;

        rectFire3.left = rectFire3.left + rectFire3.getWidth() / 3;
        rectFire3.right = rectFire3.right + rectFire3.getWidth() / 3;


        rectFire2.bottom = rectFBg.getCenter().getPointY() + woodLength / 3;
        rectFire2.top = rectFBg.getCenter().getPointY() - woodLength / 3;
        rectFire2.left = rectFBg.getCenter().getPointX() - woodLength / 3;
        rectFire2.right = rectFBg.getCenter().getPointX() + woodLength / 3;


        rectFire1.bottom = rectFBg.getCenter().getPointY() + woodLength / 4 + woodLength / 4;
        rectFire1.top = rectFBg.getCenter().getPointY() - woodLength / 4 + woodLength / 4;
        rectFire1.left = rectFBg.getCenter().getPointX() - woodLength / 4;
        rectFire1.right = rectFBg.getCenter().getPointX() + woodLength / 4;


        rectFire1.left = rectFire1.left - rectFire1.getWidth() / 5;
        rectFire1.right = rectFire1.right - rectFire1.getWidth() / 5;


        rectFire0.bottom = rectFWood.getCenter().getPointY() + rectFWood.getHeight() / 2;
        rectFire0.top = rectFWood.getCenter().getPointY() - rectFWood.getHeight() / 2;
        rectFire0.left = rectFWood.getCenter().getPointX() - rectFWood.getHeight() / 2;
        rectFire0.right = rectFWood.getCenter().getPointX() + rectFWood.getHeight() / 2;


    }




    public float getFontlength(Paint paint, String str) {
        return paint.measureText(str);
    }

    public float getFontHeight(Paint paint) {
        Paint.FontMetrics fm = paint.getFontMetrics();
        return fm.descent - fm.ascent;
    }

    public int dip2px(float dpValue) {
        final float scale = AttrHelper.getDensity(getContext());
        return (int) (dpValue * scale + 0.5f);
    }



    private float mAnimatedValue = 0.5f;






    @Override
    protected void InitPaint() {
        initPaint();
    }

    @Override
    protected void OnAnimationUpdate(AnimatorValue valueAnimator, float v) {
        mAnimatedValue = v;
        invalidate();
    }

    @Override
    protected void OnAnimationRepeat(Animator animation) {

    }





    @Override
    protected int OnStopAnim() {
        mAnimatedValue = 0.25f;
        valueAnimator=null;
        invalidate();
        return 1;
    }

    @Override
    protected int SetAnimRepeatMode() {
        return RESTART;
    }


    public boolean isAnimatorRunning() {

        if (valueAnimator == null) {
            return false;
        } else {
            if (valueAnimator.isRunning()) {
                return true;
            }

        }
        return false;
    }
    @Override
    protected void AinmIsRunning() {

    }
    @Override
    protected int SetAnimRepeatCount() {
        return -1;
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {

        canvas.save();


        rectFBg = new RectFloat(getMeasuredWidth / 2 - mWidth / 2 + mPadding
                , getMeasuredHeight / 2 - mWidth / 2 + mPadding
                , getMeasuredWidth / 2 + mWidth / 2 - mPadding
                , getMeasuredHeight / 2 + mWidth / 2 - mPadding);
        woodWidth = (int) (rectFBg.getHeight() / 12f);
        woodLength = (int) (rectFBg.getWidth() / 3 * 2);
        rectFWood = new RectFloat();
        rectFWood.bottom = rectFBg.bottom - woodWidth * 2;
        rectFWood.top = rectFBg.bottom - woodWidth * 3;
        rectFWood.left = rectFBg.getCenter().getPointX() - woodLength / 2f;
        rectFWood.right = rectFBg.getCenter().getPointX() + woodLength / 2f;
//        canvas.drawRect(rectFBg, mPaintBg);

        initFire();
        if(valueAnimator!=null) {
            drawFire3(canvas);
            drawFire2(canvas);
            drawFire1(canvas);
            drawFire0(canvas);
        }
        canvas.drawPixelMapHolder(new PixelMapHolder(getWood()), 0, 0, mPaintBg);
        canvas.restore();
    }

    @Override
    public boolean onEstimateSize(int i, int i1) {
        int widthSpecMode = EstimateSpec.getMode(i);
        int widthSpecSize = EstimateSpec.getSize(i);
        int heightSpecMode = EstimateSpec.getMode(i1);
        int heightSpecSize = EstimateSpec.getSize(i1);
        getMeasuredHeight = heightSpecSize;
        getMeasuredWidth = widthSpecSize;
        if (widthSpecMode == EstimateSpec.NOT_EXCEED
                && heightSpecMode == EstimateSpec.NOT_EXCEED) {
            setEstimatedSize(dip2px(30), dip2px(30));
        } else if (widthSpecMode == EstimateSpec.NOT_EXCEED) {
            setEstimatedSize(heightSpecSize, heightSpecSize);
        } else if (heightSpecMode == EstimateSpec.NOT_EXCEED) {
            setEstimatedSize(widthSpecSize, widthSpecSize);
        }
        if (EstimateSpec.getSize(i) > getHeight())
            mWidth = EstimateSpec.getSize(i1);
        else
            mWidth = EstimateSpec.getSize(i);
        return false;
    }

    @Override
    public void onRefreshed(Component component) {
        int h = component.getHeight();
        int w = component.getWidth();
        if (h != oldH || w != oldW) {
            if (w > h)
                mWidth = h;
            else
                mWidth = w;
        }
        oldH = h;
        oldW = w;
    }
}
